package com.anti.modular.owner.ownerlease.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.anti.core.context.login.LoginContextHolder;
import com.anti.jdbc.DBUtils;
import com.anti.jdbc.support.page.PageParam;
import com.anti.jdbc.support.page.PageResult;
import com.anti.commom.core.exception.BusinessException;
import com.anti.modular.bus.housebill.entity.HouseBill;
import com.anti.modular.commonutils.CalculateQs;
import com.anti.modular.owner.ownerlease.entity.BusFile;
import com.anti.modular.owner.ownerlease.entity.OwnerLease;
import com.anti.modular.owner.ownerlease.entity.OwnerLeaseEditResult;
import com.anti.modular.owner.ownerlease.enums.OwnerLeaseExceptionEnum;
import com.anti.modular.owner.ownerlease.param.OwerGdfy;
import com.anti.modular.owner.ownerlease.param.OwerRoom;
import com.anti.modular.owner.ownerlease.param.OwnerLeaseParam;
import com.anti.modular.owner.ownerlease.service.OwnerLeaseService;
import com.anti.modular.owner.ownerleasebill.entity.OwnerLeaseBill;
import com.anti.modular.owner.ownerleasebill.service.OwnerLeaseBillService;
import com.anti.modular.owner.ownerleasebilldetail.service.OwnerLeaseBillDetailService;
import com.anti.modular.owner.ownerleasefees.entity.OwnerLeaseFees;
import com.anti.modular.owner.ownerleasefees.service.OwnerLeaseFeesService;
import com.anti.modular.owner.ownerleaseroom.entity.OwnerLeaseRoom;
import com.anti.modular.owner.ownerleaseroom.service.OwnerLeaseRoomService;
import com.sun.jndi.dns.DnsUrl;
import org.aspectj.weaver.ast.Var;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * 業主租約service接口实现类
 *
 * @author anti
 * @date 2021-05-20 14:23:14
 */
@Service
public class OwnerLeaseServiceImpl implements OwnerLeaseService {
    @Resource
    DBUtils dbUtils;
    @Resource
    OwnerLeaseRoomService ownerLeaseRoomService;
    @Resource
    OwnerLeaseBillService ownerLeaseBillService;
    @Resource
    OwnerLeaseBillDetailService ownerLeaseBillDetailService;
    @Resource
    OwnerLeaseFeesService ownerLeaseFeesService;

    @Override
    public OwnerLease getById(OwnerLeaseParam ownerLeaseParam){
        String sql="select * from owner_lease where id =? ";
        return dbUtils.get(sql,OwnerLease.class,ownerLeaseParam.getId());
    }

    @Override
    public OwnerLease getByLeaseById(Long id) {
        String sql="select * from owner_lease where id =? ";
        return dbUtils.get(sql,OwnerLease.class,id);
    }

    @Override
    public PageResult page(PageParam pageParam,OwnerLeaseParam ownerLeaseParam) {

        StringBuilder sb=new StringBuilder("select * from owner_lease where 1=1 ");
        ArrayList<Object> param = CollectionUtil.newArrayList();
        if (ObjectUtil.isNotNull(ownerLeaseParam)) {
            if (ObjectUtil.isNotEmpty(ownerLeaseParam.getType())){
                if (ownerLeaseParam.getType()==1){
                    sb.append(" and lease_status <> 2");
                }else {
                    sb.append(" and lease_status = 2");
                }
            }
            // 根据業主名稱 查询
            if (ObjectUtil.isNotEmpty(ownerLeaseParam.getSearchType())&&ObjectUtil.isNotEmpty(ownerLeaseParam.getSearchValue())) {
                String searchType = ownerLeaseParam.getSearchType();
                if ("1".equals(searchType)){
                    sb.append(" and id in ( select owner_lease_id from  owner_lease_room where room_id in ( select id from bus_room where estateid in (select id from bus_real_estate where status =0 and name like ? )))");
                    param.add(ownerLeaseParam.getSearchValue()+"%");
                }else if ("2".equals(searchType)){
                    sb.append(" and id in (select owner_lease_id from  owner_lease_room where room_id in ( select id from bus_room where code  like ? ))");
                    param.add(ownerLeaseParam.getSearchValue()+"%");
                }else if ("3".equals(searchType)){
                    sb.append(" and name  like ? ");
                    param.add("%"+ownerLeaseParam.getSearchValue()+"%");
                }else if ("4".equals(searchType)){
                    sb.append(" and phone  like ? ");
                    param.add(ownerLeaseParam.getSearchValue()+"%");
                }
            }
        }
        sb.append(" order by create_time desc");
        return dbUtils.query(pageParam,sb.toString(),param.toArray());
    }

    @Override
    public List<OwnerLease> list(OwnerLeaseParam ownerLeaseParam) {
        String sql="";
        return dbUtils.query(sql,OwnerLease.class);
    }

    @Override
    public void add(OwnerLeaseParam ownerLeaseParam) {
        List<OwerRoom> roomList = ownerLeaseParam.getRoomList();
        List<BusFile> files = ownerLeaseParam.getFiles();
        List<OwerGdfy> gdfy = ownerLeaseParam.getGdfy();
        check(roomList);
        OwnerLease ownerLease = new OwnerLease();
        BeanUtil.copyProperties(ownerLeaseParam, ownerLease);
        Date date = new Date();
        Long sysLoginUserId = LoginContextHolder.me().getSysLoginUserId();
        ownerLease.setCreateTime(date);
        ownerLease.setStatus(0);
        ownerLease.setLeaseStatus(1);
        ownerLease.setCreateUser(sysLoginUserId);
        String zqName = getZqName(ownerLease);
        ownerLease.setReceiptCycle(zqName);
        String key = dbUtils.insertKey(ownerLease).toString();
        long pKey = Long.parseLong(key);
        ownerLease.setId(pKey);
        //新增業主房間關聯
        ownerLeaseRoomService.addByList(roomList,pKey);
        //文件關聯
        files.forEach(item->{
            item.setBusId(pKey);
            item.setType(2);
            dbUtils.insert(item);
        });
        //固定費用
        List<OwnerLeaseFees> ownerLeaseFees = ownerLeaseFeesService.addGdfyAndReturn(gdfy, pKey);
        ownerLeaseBillService.addBillListByLease(ownerLease,ownerLeaseFees);
    }

    @Override
    public void editYzXx(OwnerLeaseParam ownerLeaseParam) {
        OwnerLease ownerLease = this.queryOwnerLease(ownerLeaseParam);
        ownerLease.setName(ownerLeaseParam.getName());
        ownerLease.setPhone(ownerLeaseParam.getPhone());
        ownerLease.setUpdateUser(LoginContextHolder.me().getSysLoginUserId());
        ownerLease.setUpdateTime(new Date());
        dbUtils.update(ownerLease);
        List<BusFile> files = ownerLeaseParam.getFiles();
        Long pKey = ownerLease.getId();
        deleteBusFiles(pKey,2);
        //文件關聯
        files.forEach(item->{
            item.setBusId(pKey);
            item.setType(2);
            dbUtils.insert(item);
        });
    }

    @Override
    public void editZyZqFy(OwnerLeaseParam ownerLeaseParam) {
        OwnerLease ownerLease = this.queryOwnerLease(ownerLeaseParam);
        Long ownerLeaseId = ownerLease.getId();
        int receiptFu = ownerLease.getReceiptFu();
        int receiptYj = ownerLease.getReceiptYj();
        int receiptFu1 = ownerLeaseParam.getReceiptFu();
        ownerLease.setReceiptFu(receiptFu1);
        int receiptYj1 = ownerLeaseParam.getReceiptYj();
        ownerLease.setReceiptYj(receiptYj1);
        int billEndTqData = ownerLease.getBillEndTqData();
        int billEndTqData1 = ownerLeaseParam.getBillEndTqData();
        ownerLease.setBillEndTqData(billEndTqData1);
        Long sysLoginUserId = LoginContextHolder.me().getSysLoginUserId();
        Date date = new Date();
        ownerLease.setUpdateUser(sysLoginUserId);
        ownerLease.setUpdateTime(date);
        dbUtils.update(ownerLease);
        ownerLeaseFeesService.deleteByLeaseId(ownerLeaseId);
        List<OwerGdfy> gdfy = ownerLeaseParam.getGdfy();
        ownerLeaseFeesService.addGdfyAndReturn(gdfy,ownerLeaseId);
        OwnerLeaseBill nowYxById = ownerLeaseBillService.getNowYxById(ownerLeaseId);
        ArrayList<OwnerLeaseFees> ownerLeaseFees = CollectionUtil.newArrayList();
        gdfy.forEach(item->{
            OwnerLeaseFees fees=new OwnerLeaseFees();
            fees.setFeesId(item.getRentAmountCategory());
            fees.setFeesName(item.getRentAmountName());
            fees.setAmount(item.getAmount());
            ownerLeaseFees.add(fees);
        });
        if (receiptFu!=receiptFu1||receiptYj!=receiptYj1){
            //说明周期修改，进行账单周期重新生成
            if (null!=nowYxById){
                int startQsNum = nowYxById.getQsNum();
                ownerLease.setLeaseStatus(1);
                dbUtils.update(ownerLease);
                ownerLeaseBillService.addNewBillPlanByLease(startQsNum,ownerLease,nowYxById,ownerLeaseFees);
            }
        }else {
            //只调整当前生效周期固定费用
            if (null!=nowYxById){
                ownerLeaseBillDetailService.deleteByOwnerBillIdOnType(nowYxById.getId(),3);
                ownerLeaseBillDetailService.addGdfy(ownerLeaseFees,nowYxById.getId());
                Date rentedDay = CalculateQs.createRentedDay(billEndTqData, nowYxById.getRentStartDate());
                nowYxById.setRentedDay(rentedDay);
                nowYxById.setUpdateUser(sysLoginUserId);
                nowYxById.setUpdateTime(date);
                dbUtils.update(nowYxById);
            }
        }
    }

    @Override
    public void editTxxxAndAc(OwnerLeaseParam ownerLeaseParam) {
        OwnerLease ownerLease = this.queryOwnerLease(ownerLeaseParam);
        ownerLease.setAccountType(ownerLeaseParam.getAccountType());
        ownerLease.setCardHolder(ownerLeaseParam.getCardHolder());
        ownerLease.setCardNumber(ownerLeaseParam.getCardNumber());
        ownerLease.setCardBankType(ownerLeaseParam.getCardBankType());
        ownerLease.setAccount(ownerLeaseParam.getAccount());
        ownerLease.setPayee(ownerLeaseParam.getPayee());
        ownerLease.setRentReminderSwitch(ownerLeaseParam.getRentReminderSwitch());
        ownerLease.setRentReminderDay(ownerLeaseParam.getRentReminderDay());
        ownerLease.setRentReminderHour(ownerLeaseParam.getRentReminderHour());
        ownerLease.setRentReminderMinutes(ownerLeaseParam.getRentReminderMinutes());
        ownerLease.setRemark(ownerLeaseParam.getRemark());
        ownerLease.setUpdateTime(new Date());
        ownerLease.setUpdateUser(LoginContextHolder.me().getSysLoginUserId());
        dbUtils.update(ownerLease);
    }

    public void delete(OwnerLeaseParam ownerLeaseParam) {
        String sql="delete  from owner_lease where id =? ";
        dbUtils.execSql(sql,ownerLeaseParam.getId());
    }

    public void edit(OwnerLeaseParam ownerLeaseParam) {
        OwnerLease ownerLease = this.queryOwnerLease(ownerLeaseParam);
        BeanUtil.copyProperties(ownerLeaseParam, ownerLease);
        dbUtils.update(ownerLease);
    }

    @Override
    public void editXz(OwnerLeaseParam ownerLeaseParam) {
        OwnerLease ownerLease = this.queryOwnerLease(ownerLeaseParam);
        Long id = ownerLease.getId();
        checkBillIsTcs(id);
        //删除结算账单
        String sql="select * from owner_lease_bill where owner_lease_id =? and status=0 and bill_status=3";
        HouseBill first = dbUtils.getFirst(sql, HouseBill.class, id);
        if (null!=first){
            //删除账单及其详情 清算賬單需要刪除
            ownerLeaseBillDetailService.deleteXuByOwnerBillId(first.getId());
        }
        //修改租約日期
        String rentEndDate = ownerLeaseParam.getRentEndDate();
        DateTime rentEndDates = DateUtil.parse(rentEndDate, "yyyy-MM-dd");
        ownerLease.setRentEndDate(rentEndDates);
        ownerLease.setLeaseStatus(1);
        ownerLease.setUpdateTime(new Date());
        ownerLease.setUpdateUser(LoginContextHolder.me().getSysLoginUserId());
        dbUtils.update(ownerLease);
        //生成後續賬單週期
        int maxQs = getMaxQs(id);
        String rentStart = ownerLeaseParam.getRentStartDate();
        DateTime rentStarts = DateUtil.parse(rentStart, "yyyy-MM-dd");
        ownerLeaseBillService.addXuZuBillListByLease(maxQs,ownerLease,rentStarts,rentEndDates);
    }

    private int getMaxQs(Long id) {
        String sqlQs="select max(qs_num) from owner_lease_bill where owner_lease_id =? and status=0 and bill_status<>3";
        return dbUtils.getIntValue(sqlQs, id);
    }

    @Override
    public void editTuiZu(OwnerLeaseParam ownerLeaseParam) {
        checkBillIsTzTcs(ownerLeaseParam.getId());
        // 修改賬單為退租清算狀態
        OwnerLease ownerLease = this.queryOwnerLease(ownerLeaseParam);
        String retrieveDate = ownerLeaseParam.getRetrieveDate();
        ownerLease.setRetrieveDate(DateUtil.parse(retrieveDate,"yyyy-MM-dd"));
        ownerLease.setLeaseStatus(3);
        ownerLease.setUpdateTime(new Date());
        ownerLease.setUpdateUser(LoginContextHolder.me().getSysLoginUserId());
        dbUtils.update(ownerLease);
        //生成清算賬單
        int maxQs = getMaxQs(ownerLease.getId());
        ownerLeaseBillService.addQsBillListByLease(ownerLease,maxQs);
    }

    @Override
    public void editTuiZuQs(Long id) {
        String updateSql="update owner_lease set lease_status=2,update_time=?,update_user=? where id =?";
        dbUtils.execSql(updateSql,new Date(),LoginContextHolder.me().getSysLoginUserId(),id);
    }

    private void checkBillIsTcs(Long id) {
        String sql="select count(*) from owner_lease where id =? and lease_status =2  and status=0 ";
        int intValue = dbUtils.getIntValue(sql, id);
        if (intValue>0){
            throw new BusinessException(0,"該業主已退租不允许修改！");
        }
    }
    private void checkBillIsTzTcs(Long id) {
        String sql="select count(*) from owner_lease where id =? and lease_status =1  and status=0 ";
        int intValue = dbUtils.getIntValue(sql, id);
        if (intValue ==0){
            throw new BusinessException(0,"該業主已退租或已進入清算環節不允许修改！");
        }
    }

    @Override
    public OwnerLease detail(OwnerLeaseParam ownerLeaseParam) {
        return this.queryOwnerLease(ownerLeaseParam);
    }

    @Override
    public OwnerLeaseEditResult detailForEdit(Long leaseId) {
        String sql="select * from owner_lease where id =? ";
        OwnerLeaseEditResult ownerLease = dbUtils.get(sql,OwnerLeaseEditResult.class,leaseId);
        Long id = ownerLease.getId();
        List<OwnerLeaseRoom> roomNamesByOwnerId = ownerLeaseRoomService.getRoomNamesByOwnerId(id);
        ownerLease.setRoomList(roomNamesByOwnerId);
        List<BusFile> query = getBusFiles(id,2);
        ownerLease.setFileList(query);
        List<OwerGdfy> owerGdfyByLeaseId = ownerLeaseFeesService.getOwerGdfyByLeaseId(leaseId);
        ownerLease.setGdfyList(owerGdfyByLeaseId);
        return ownerLease;
    }

    public List<BusFile> getBusFiles(Long id,int type) {
        String sqlFile="select * from bus_file where bus_id=? and type=?";
        return dbUtils.query(sqlFile, BusFile.class, id,type);
    }

    public void deleteBusFiles(Long id,int type) {
        String sqlFile="delete from bus_file where bus_id=? and type=?";
        dbUtils.execSql(sqlFile,id,type);
    }
    /**
     * 获取業主租約
     *
     * @author anti
     * @date 2021-05-20 14:23:14
     */
    private OwnerLease queryOwnerLease(OwnerLeaseParam ownerLeaseParam) {
        OwnerLease ownerLease = this.getById(ownerLeaseParam);
        if (ObjectUtil.isNull(ownerLease)) {
            throw new BusinessException(OwnerLeaseExceptionEnum.NOT_EXIST);
        }
        return ownerLease;
    }

    private void check(List<OwerRoom> roomList) {
        if (roomList.size()==0){
            throw new BusinessException(0,"請選擇簽約房間！");
        }
        String sql="select count(*) from bus_room where id in (:ids) and status=0 and owner =1";
        ArrayList<Long> objects = CollectionUtil.newArrayList();
        roomList.forEach(it->{
            objects.add(it.getId());
        });
        HashMap<Object, Object> param = CollectionUtil.newHashMap();
        param.put("ids",objects);
        int intValue = dbUtils.getIntValue(sql, param);
        if (intValue>0){
            throw new BusinessException(0,"提交簽約房間中已存在被其他業主簽約的房間！");
        }
    }


    public String getZqName(OwnerLease ownerLease){
        // 依据（字典 1日 2月 3年 4一次付清）
        int receiptyj = ownerLease.getReceiptYj();
        // 付 （字典 付1-付18）
        int receiptfu = ownerLease.getReceiptFu();
        // 押 （字典 押1-押18-自定义19）
        int receiptya = ownerLease.getReceiptYa();
        if (receiptyj == 4){
            return "一次付清";
        }
        String dw="月";
        if (receiptyj == 1){
            dw="日";
        }else if (receiptyj == 2){
            dw="月";
        }else if (receiptyj == 3){
            dw="年";
        }

        if (receiptya==19){
            return "付"+receiptfu+dw+" 押金自定義";
        }
        return "付"+receiptfu+dw+" 押"+receiptya+dw;
    }
}
